package com.yungu.swift.assets.passenger.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alicp.jetcache.anno.Cached;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.assets.passenger.dao.PassengerLogMapper;
import com.yungu.swift.assets.passenger.dao.PassengerMapper;
import com.yungu.swift.assets.passenger.dao.PassengerPunishLogMapper;
import com.yungu.swift.assets.passenger.model.dto.PassengerBlockedLogDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerCouponDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerLogDto;
import com.yungu.swift.assets.passenger.model.param.AdminPassengerAbortParam;
import com.yungu.swift.assets.passenger.model.param.AdminPassengerPageParam;
import com.yungu.swift.assets.passenger.model.param.ApiPassengerLoginParam;
import com.yungu.swift.assets.passenger.model.vo.PassengerSimpleInfoVo;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerCouponService;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.assets.utils.RandomNameUtils;
import com.yungu.swift.autoconfig.redis.RedisCacheService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.constants.FinanceConstant;
import com.yungu.swift.constants.PassengerConstant;
import com.yungu.swift.lbs.model.vo.RegeoVo;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.socket.push.model.PushContent;
import com.yungu.swift.socket.push.service.PushService;
import com.yungu.swift.system.finance.model.dto.FinanceInviteRewardDto;
import com.yungu.swift.system.finance.service.FinanceInviteRewardService;
import com.yungu.swift.system.marketing.model.dto.MarketingChannelLogDto;
import com.yungu.swift.system.marketing.model.dto.MarketingCouponDto;
import com.yungu.swift.system.marketing.model.dto.MarketingGiftDto;
import com.yungu.swift.system.marketing.model.dto.MarketingInviteLogDto;
import com.yungu.swift.system.marketing.model.param.AdminGiftUuidPageParam;
import com.yungu.swift.system.marketing.service.*;
import com.yungu.swift.system.sys.model.dto.*;
import com.yungu.swift.system.sys.service.*;
import com.yungu.swift.utils.DateUtils;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.yungu.swift.assets.passenger.model.enums.PassengerErrorEnum.PASSENGER_STATUS_INVALID;
import static com.yungu.swift.constants.PassengerConstant.PASSENGER_STATUS_LONG_CLOSE;
import static com.yungu.swift.constants.PassengerConstant.PASSENGER_STATUS_SHORT_CLOSE;


/**
 * 乘客业务逻辑接口实现类
 *
 * @author cuixiuyin - Generate
 * @version 1.1.1-SNAPSHOT
 * @since 2018-07-02 11:20
 */
@Service
public class PassengerServiceImpl extends BaseServiceImpl<PassengerDto> implements PassengerService {

    private static final Logger logger = LoggerFactory.getLogger(PassengerServiceImpl.class);

    @Autowired
    private PassengerMapper passengerMapper;
    @Autowired
    private PassengerLogMapper passengerLogMapper;
    @Autowired
    private PassengerPunishLogMapper passengerPunishLogMapper;
    @Autowired
    private DriverService driverService;
    @Autowired
    private RedisCacheService redisCacheService;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @Reference
    private MarketingCouponService marketingCouponService;
    @Reference
    private MarketingGiftService marketingGiftService;
    @Reference
    private PassengerCouponService passengerCouponService;
    @Reference
    private MarketingInviteLogService marketingInviteLogService;
    @Reference
    private MarketingChannelService marketingChannelService;
    @Reference
    private MarketingChannelLogService marketingChannelLogService;
    @Reference
    private SysAccountPlatformService sysAccountPlatformService;
    @Reference
    private SysAccountDriverService sysAccountDriverService;
    @Reference
    private FinanceInviteRewardService financeInviteRewardService;
    @Reference
    private SysAreaService sysAreaService;
    @Reference
    private SysCityService sysCityService;
    @Reference
    private SysAccountPassengerService sysAccountPassengerService;
    @Reference
    private LocationService locationService;
    @Reference
    private PushService pushService;

    private final static ExecutorService POOL = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            100, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("passenger-pool").build(),
            new ThreadPoolExecutor.CallerRunsPolicy());


    @Override
    protected IMapper<PassengerDto> getMapper() {
        return passengerMapper;
    }

    @Override
    public ResponseData<PassengerVo> login(PassengerDto passengerDto, PassengerLogDto passengerLogDto) {
        // 默认账号是激活，有可能领取二维码礼包时需要帮用户伪注册一个账号，所以这边加上一个参数判断是伪注册
        return login(passengerDto, passengerLogDto, 1, null);
    }

    @Override
    public ResponseData<PassengerVo> login(PassengerDto passengerParam, PassengerLogDto passengerLogDto, Integer active, String giftUuid) {
        //返回乘客详细信息
        PassengerVo passengerVo = new PassengerVo();
        //查找是否存在用户
        Map<String, Object> map = MapUtils.build(4);
        map.put("mobile", passengerParam.getMobile());
        map.put("appid", passengerParam.getAppid());
        List<PassengerDto> passengers = passengerMapper.list(map);
        // 老用户登陆
        if (CollectionUtils.isNotEmpty(passengers)) {
            PassengerDto oldPasDto = passengers.get(0);
            String adCode = getAdCodeByLngLat(StringUtils.nullToString(passengerLogDto.getLng()), StringUtils.nullToString(passengerLogDto.getLat()));
            //更新乘客所在区域
            String passengerCityUuid = passengerCityUuid(adCode);
            passengerParam.setCurrentAdCode(adCode);
            passengerParam.setCityUuid(passengerCityUuid);
            // 长期封号
            if (PassengerConstant.PASSENGER_STATUS_LONG_CLOSE.equals(oldPasDto.getStatus())) {
                StringBuffer buffer = new StringBuffer();
                buffer.append("您的账号已被封，原因是:")
                        .append(oldPasDto.getAbortRemark())
                        .append("。如有疑问请联系客服");
                return ResponseData.buildErrorResponse(PASSENGER_STATUS_INVALID.getCode(), buffer.toString());
            }
            // 短期封号
            if (PassengerConstant.PASSENGER_STATUS_SHORT_CLOSE.equals(oldPasDto.getStatus())) {
                if (oldPasDto.getAbortTime() == null || new Date().after(oldPasDto.getAbortTime())) {
                    passengerParam.setStatus(PassengerConstant.PASSENGER_STATUS_NORMAL);
                    passengerParam.setUuid(oldPasDto.getUuid());
                    passengerParam.setToken(StringUtils.buildUUID());
                    passengerParam.setUpdateOn(new Date());
                    passengerParam.setLastLogin(new Date());
                    passengerMapper.edit(passengerParam);
                    passengerVo.setIsFirst(PassengerConstant.IS_NO_FIRST);
                } else {
                    StringBuffer errmsg = new StringBuffer();
                    errmsg.append("您的账号已被封，原因是:")
                            .append(oldPasDto.getAbortRemark())
                            .append("，解封日期：")
                            .append(DateUtils.format(oldPasDto.getAbortTime()))
                            .append("。如有疑问请联系客服");
                    return ResponseData.buildErrorResponse(PASSENGER_STATUS_INVALID.getCode(), errmsg.toString());
                }
            }
            // 状态正常
            if (PassengerConstant.PASSENGER_STATUS_NORMAL.equals(oldPasDto.getStatus())) {
                passengerParam.setUuid(oldPasDto.getUuid());
                passengerParam.setToken(StringUtils.buildUUID());
                passengerParam.setUpdateOn(new Date());
                passengerParam.setLastLogin(new Date());
                passengerMapper.edit(passengerParam);
                passengerVo.setIsFirst(PassengerConstant.IS_NO_FIRST);
            }
            POOL.execute(() -> savePassengerLog(oldPasDto.getUuid(), 2, passengerLogDto));
        }
        // 新用户登录
        if (CollectionUtils.isEmpty(passengers)) {
            //默认余额为0
            passengerParam.setStatus(PassengerConstant.PASSENGER_STATUS_NORMAL);
            passengerParam.setOrderCount(0);
            passengerParam.setSex(PassengerConstant.SEX_MAN);
            passengerParam.setToken(StringUtils.buildUUID());
            passengerParam.setUuid(StringUtils.buildUUID());
            passengerParam.setCreateOn(new Date());
            passengerParam.setLastLogin(new Date());
            passengerParam.setActive(active);
            passengerParam.setNickname(RandomNameUtils.randomName());
            // 注册礼包领取
            registrationGift(active, passengerLogDto.getLng(), passengerLogDto.getLat(), passengerParam, giftUuid);
            passengerMapper.add(passengerParam);
            //同步新增乘客账户
            SysAccountPassengerDto accountPassengerDto = new SysAccountPassengerDto();
            String mobile = passengerParam.getMobile();
            accountPassengerDto.setUuid(passengerParam.getUuid());
            accountPassengerDto.setAppid(passengerParam.getAppid());
            accountPassengerDto.setAccountName("用户" + StringUtils.right(mobile, 4));
            accountPassengerDto.setPresentBalance(BigDecimal.ZERO);
            accountPassengerDto.setRechargeBalance(BigDecimal.ZERO);
            accountPassengerDto.setAlipayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setTenpayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setCreateOn(new Date());
            sysAccountPassengerService.add(accountPassengerDto);
            passengerVo.setIsFirst(PassengerConstant.IS_FIRST);
            // 用户注册日志
            POOL.execute(() -> {
                Map<String, Object> regParams = MapUtils.build(8);
                regParams.put("uuid", StringUtils.buildUUID());
                regParams.put("appid", passengerParam.getAppid());
                regParams.put("passengerUuid", passengerParam.getUuid());
                regParams.put("type", active == 1 ? 1 : 4);
                passengerLogMapper.saveRegisterLog(regParams);
            });
            // 用户登录日志
            POOL.execute(() -> savePassengerLog(passengerParam.getUuid(), 1, passengerLogDto));
        }
        //过滤不必要的字段
        map.clear();
        map.put("uuid", passengerParam.getUuid());
        map.put("appid", passengerParam.getAppid());
        PassengerDto tempPassenger = passengerMapper.list(map).get(0);
        BeanUtils.copyProperties(tempPassenger, passengerVo);
        //添加乘客部分参数到缓存中
        updateCached(passengerParam.getToken(), passengerVo);
        return ResponseData.buildSuccessResponse("登陆成功", passengerVo);
    }

    @Override
    public ResponseData<PassengerVo> login(ApiPassengerLoginParam passengerLoginParam) {
        //返回乘客详细信息
        PassengerVo passengerVo = new PassengerVo();
        List<PassengerDto> passengerDtos = passengerMapper.list(MapUtils.build("mobile", passengerLoginParam.getMobile()));
        // 老用户登陆
        if (CollectionUtils.isNotEmpty(passengerDtos)) {
            PassengerDto oldPasDto = passengerDtos.get(0);
            String adCode = getAdCodeByLngLat(StringUtils.nullToString(passengerLoginParam.getLng()), StringUtils.nullToString(passengerLoginParam.getLat()));
            //更新乘客所在区域
            String passengerCityUuid = passengerCityUuid(adCode);
            oldPasDto.setCurrentAdCode(adCode);
            oldPasDto.setCityUuid(passengerCityUuid);
            // 长期封号
            if (PASSENGER_STATUS_LONG_CLOSE.equals(oldPasDto.getStatus())) {
                StringBuilder builder = new StringBuilder();
                builder.append("您的账号已被封，原因是:").append(oldPasDto.getAbortRemark()).append("。如有疑问请联系客服");
                return ResponseData.buildErrorResponse(PASSENGER_STATUS_INVALID.getCode(), builder.toString());
            }
            // 短期封号
            if (PASSENGER_STATUS_SHORT_CLOSE.equals(oldPasDto.getStatus())) {
                if (oldPasDto.getAbortTime() == null || new Date().after(oldPasDto.getAbortTime())) {
                    PassengerDto passengerDto = new PassengerDto();
                    passengerDto.setUuid(oldPasDto.getUuid());
                    passengerDto.setStatus(PassengerConstant.PASSENGER_STATUS_NORMAL);
                    passengerDto.setUpdateOn(new Date());
                    passengerDto.setLastLogin(new Date());
                    passengerMapper.edit(passengerDto);
                } else {
                    StringBuilder builder = new StringBuilder();
                    builder.append("您的账号已被封，原因是:").append(oldPasDto.getAbortRemark()).append("，解封日期：")
                            .append(DateUtils.format(oldPasDto.getAbortTime())).append("。如有疑问请联系客服");
                    return ResponseData.buildErrorResponse(PASSENGER_STATUS_INVALID.getCode(), builder.toString());
                }
            }
            // 状态正常
            if (PassengerConstant.PASSENGER_STATUS_NORMAL.equals(oldPasDto.getStatus())) {
                PassengerDto passengerDto = new PassengerDto();
                passengerDto.setUuid(oldPasDto.getUuid());
                passengerDto.setUpdateOn(new Date());
                passengerDto.setLastLogin(new Date());
                passengerDto.setOpenId(passengerLoginParam.getOpenId());
                passengerMapper.edit(passengerDto);
            }
            POOL.execute(() -> savePassengerLog(oldPasDto.getUuid(), 2, passengerLoginParam));
            passengerVo.setIsFirst(PassengerConstant.IS_NO_FIRST);
            BeanUtils.copyProperties(oldPasDto, passengerVo);
            return ResponseData.buildSuccessResponse(passengerVo);
        }
        // 新用户登录
        else {
            //默认余额为0
            PassengerDto passengerDto = new PassengerDto();
            String uuid = StringUtils.buildUUID();
            passengerDto.setUuid(uuid);
            passengerDto.setOpenId(passengerLoginParam.getOpenId());
            passengerDto.setAppid(passengerLoginParam.getAppid());
            passengerDto.setMobile(passengerLoginParam.getMobile());
            passengerDto.setStatus(PassengerConstant.PASSENGER_STATUS_NORMAL);
            passengerDto.setOrderCount(0);
            passengerDto.setPoint(0);
            passengerDto.setActive(1);
            passengerDto.setSex(PassengerConstant.SEX_MAN);
            passengerDto.setCreateOn(new Date());
            passengerDto.setLastLogin(new Date());
            passengerDto.setNickname(RandomNameUtils.randomName());
            // 注册礼包领取
            registrationGift(1, passengerLoginParam.getLng(), passengerLoginParam.getLat(), passengerDto, passengerLoginParam.getGiftUuid());
            passengerMapper.add(passengerDto);
            //同步新增乘客账户
            SysAccountPassengerDto accountPassengerDto = new SysAccountPassengerDto();
            accountPassengerDto.setUuid(passengerDto.getUuid());
            accountPassengerDto.setAppid(passengerDto.getAppid());
            accountPassengerDto.setAccountName("用户" + StringUtils.right(passengerLoginParam.getMobile(), 4));
            accountPassengerDto.setPresentBalance(BigDecimal.ZERO);
            accountPassengerDto.setRechargeBalance(BigDecimal.ZERO);
            accountPassengerDto.setAlipayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setTenpayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setCreateOn(new Date());
            sysAccountPassengerService.add(accountPassengerDto);
            passengerVo.setIsFirst(PassengerConstant.IS_FIRST);
            BeanUtils.copyProperties(passengerDto, passengerVo);
            // 用户注册日志
            POOL.execute(() -> savePassengerLog(passengerDto.getUuid(), 1, passengerLoginParam));
            // 用户登录日志
            POOL.execute(() -> savePassengerLog(passengerDto.getUuid(), 2, passengerLoginParam));
            return ResponseData.buildSuccessResponse("登陆成功", passengerVo);
        }
    }


    /**
     * 领取注册礼包
     *
     * @param active         1 注册大礼包 2 二维码/微信礼包
     * @param lng
     * @param lat
     * @param passengerParam
     * @param giftUuid
     */
    @Transactional
    public void registrationGift(Integer active, Double lng, Double lat, PassengerDto passengerParam, String giftUuid) {
        logger.info("passenger register mobile:{}", passengerParam.getMobile());
        // 注册礼包，二维码/微信 用户不领取注册礼包
        if (active == 1) {
            List<PassengerCouponDto> passengerCouponDtoList = new ArrayList<>();
            if (lng != null && lat != null) {
                String adCode = getAdCodeByLngLat(lng.toString(), lat.toString());
                //更新乘客所在区域
                String passengerCityUuid = passengerCityUuid(adCode);
                passengerParam.setCurrentAdCode(adCode);
                passengerParam.setCityUuid(passengerCityUuid);
                //获取注册礼包
                MarketingGiftDto giftParam = new MarketingGiftDto();
                giftParam.setType(1);
                giftParam.setSendCity(passengerCityUuid);
                ResponseData<List<MarketingCouponDto>> getActiveCouponsByGift = marketingCouponService.getActiveCouponsByGift(giftParam);
                if (getActiveCouponsByGift.isSuccess() && CollectionUtils.isNotEmpty(getActiveCouponsByGift.getData())) {
                    List<MarketingCouponDto> couponList = getActiveCouponsByGift.getData();
                    // 加上全国的礼包
                    giftParam.setSendCity("ALL");
                    couponList.addAll(marketingCouponService.getActiveCouponsByGift(giftParam).getData());
                    // 减少礼包数量
                    POOL.execute(() -> setGiftRemainNumberSub(1, 1, passengerCityUuid, 1));
                    // 新增乘客优惠券
                    for (MarketingCouponDto marketingCouponDto : couponList) {
                        PassengerCouponDto passengerCouponDto = new PassengerCouponDto();
                        passengerCouponDto.setUuid(StringUtils.buildUUID());
                        passengerCouponDto.setPassengerUuid(passengerParam.getUuid());
                        passengerCouponDto.setSysCouponUuid(marketingCouponDto.getUuid());
                        //设置优惠券过期时间
                        setCouponExpireTime(marketingCouponDto, passengerCouponDto);
                        passengerCouponDto.setStatus(1);
                        passengerCouponDto.setCityUuids(marketingCouponDto.getCityUuids());
                        passengerCouponDto.setCityNames(marketingCouponDto.getCityNames());
                        passengerCouponDto.setCreateOn(new Date());
                        passengerCouponDtoList.add(passengerCouponDto);
                    }
                }
                //获取乘客注册渠道
                Map<String, Object> channelParam = MapUtils.build(4);
                channelParam.put("type", 1);
                channelParam.put("sendCity", passengerCityUuid);
                // 获取乘客注册渠道id
                String channelUuid = marketingChannelService.findChannelUuidByConditions(channelParam).getData();
                // 记录渠道号
                if (StringUtils.isNotEmpty(channelUuid)) {
                    passengerParam.setChannelUuid(channelUuid);
                    POOL.execute(() -> {
                        // 记录渠道邀请日志
                        MarketingChannelLogDto marketingChannelLogDto = new MarketingChannelLogDto();
                        marketingChannelLogDto.setUuid(StringUtils.buildUUID());
                        marketingChannelLogDto.setChannelUuid(channelUuid);
                        marketingChannelLogDto.setUserUuid(passengerParam.getUuid());
                        marketingChannelLogDto.setAppid(passengerParam.getAppid());
                        marketingChannelLogDto.setCreateOn(passengerParam.getCreateOn());
                        // 新用户
                        marketingChannelLogDto.setNewUser(1);
                        marketingChannelLogService.add(marketingChannelLogDto);
                    });
                }
            }
            //批量保存乘客优惠券
            if (CollectionUtils.isNotEmpty(passengerCouponDtoList)) {
                passengerCouponService.addBatch(passengerCouponDtoList);
            }
        }
        // 二维码礼包领取时的伪注册 同样需要记录渠道号
        if (active != 1) {
            String channelUuid = marketingChannelService.findChannelUuidByConditions(MapUtils.build("giftUuid", giftUuid)).getData();
            passengerParam.setChannelUuid(channelUuid);
            // 二维码领取的渠道号邀请不记录在这里
        }
    }

    private String passengerCityUuid(String adCode) {
        String passengerCityUuid = "nothing";
        // 区县用户登录
        ResponseData<SysAreaDto> areaResponseData = sysAreaService.get(MapUtils.build("areaID", adCode));
        if (areaResponseData.isSuccess() && areaResponseData.getData() != null) {
            ResponseData<SysCityDto> cityDtoResponseData = sysCityService.get(MapUtils.build("cityID", areaResponseData.getData().getFather()));
            if (cityDtoResponseData.isSuccess() && cityDtoResponseData.getData() != null) {
                passengerCityUuid = cityDtoResponseData.getData().getUuid();
            }
        }
        // 城市
        if ("nothing".equals(passengerCityUuid)) {
            ResponseData<String> responseData = sysCityService.getCityUuidByAdCode(adCode);
            if (responseData.isSuccess() && StringUtils.isNotEmpty(responseData.getData())) {
                passengerCityUuid = responseData.getData();
            }
        }
        return passengerCityUuid;
    }

    private void savePassengerLog(String passengerUuid, int active, PassengerLogDto passengerLogDto) {
        // 登录日志为插入型，不需要更新
        passengerLogDto.setUuid(StringUtils.buildUUID());
        passengerLogDto.setPassengerUuid(passengerUuid);
        passengerLogDto.setAction(active);
        passengerLogDto.setCreateOn(new Date());
        passengerLogMapper.add(passengerLogDto);
    }

    private void savePassengerLog(String passengerUuid, int active, ApiPassengerLoginParam passengerLoginParam) {
        // 登录日志为插入型，不需要更新
        PassengerLogDto passengerLogDto = new PassengerLogDto();
        BeanUtils.copyProperties(passengerLoginParam, passengerLogDto);
        passengerLogDto.setUuid(StringUtils.buildUUID());
        passengerLogDto.setPassengerUuid(passengerUuid);
        passengerLogDto.setAction(active);
        passengerLogDto.setCreateOn(new Date());
        passengerLogMapper.add(passengerLogDto);
    }

    @Override
    public ResponseData<Map<String, String>> getPassengerCachedByToken(String token) {
        Object obj = redisCacheService.get(token);
        if (obj != null) {
            return ResponseData.buildSuccessResponse((Map<String, String>) obj);
        }
        //获取乘客信息
        List<PassengerDto> passengers = passengerMapper.list(MapUtils.build("token", token.trim()));
        if (passengers.size() > 0) {
            Map<String, String> result = new HashMap<>(8);
            PassengerDto passenger = passengers.get(0);
            result.put("uuid", passenger.getUuid());
            result.put("nickName", passenger.getNickname());
            result.put("sex", StringUtils.isNull(passenger.getSex()) ? "" : passenger.getSex().toString());
            result.put("mobile", passenger.getMobile());
            result.put("face", passenger.getFace());
            result.put("status", String.valueOf(passenger.getStatus()));
            //添加缓存
            redisCacheService.set(token, result, 3L, TimeUnit.DAYS);
            redisCacheService.set(passenger.getUuid(), token, 3L, TimeUnit.DAYS);
            return ResponseData.buildSuccessResponse(result);
        }
        return ResponseData.buildSuccessResponse(null);
    }

    @Override
    public ResponseData<List<PassengerDto>> listExport(AdminPassengerPageParam passengerPageParam) {
        return ResponseData.buildSuccessResponse(passengerMapper.listExport(MapUtils.convertObjToMap(passengerPageParam)));
    }

    @Override
    public ResponseData<Boolean> logout(String token, String appid) {
        //查找乘客信息,清空token
        Map<String, Object> map = MapUtils.build(2);
        map.put("token", token);
        map.put("appid", appid);
        List<PassengerDto> passengers = passengerMapper.list(map);
        if (passengers.size() > 0) {
            PassengerDto passenger = passengers.get(0);
            //避免插入多个重复字段，新增个临时乘客来接受
            PassengerDto editPassenger = new PassengerDto();
            editPassenger.setUuid(passenger.getUuid());
            editPassenger.setToken("");
            //清空缓存
            redisCacheService.delete(passenger.getUuid());
            redisCacheService.delete(token);
            return ResponseData.buildSuccessResponse("退出登陆成功", passengerMapper.edit(editPassenger) > 0);
        }
        return ResponseData.buildSuccessResponse("退出登陆失败", Boolean.FALSE);
    }

    @Override
    public ResponseData<Boolean> isPassenger(String uuid, String token) {
        //查询是否存在
        Map<String, Object> map = MapUtils.build(3);
        map.put("uuid", uuid);
        map.put("token", token);
        List<PassengerDto> passengers = passengerMapper.list(map);
        if (CollectionUtils.isNotEmpty(passengers)) {
            return ResponseData.buildSuccessResponse(Boolean.TRUE);
        }
        return ResponseData.buildSuccessResponse(Boolean.FALSE);
    }


    @Override
    public ResponseData<List<PassengerDto>> listExtend(Map<String, Object> params) {
        return ResponseData.buildSuccessResponse(passengerMapper.listExtend(params));
    }

    @Override
    public ResponseData<List<PassengerDto>> estimate(Map<String, Object> params) {
        return ResponseData.buildSuccessResponse(passengerMapper.estimate(params));
    }

    @Override
    public ResponseData<List<String>> getUuids(Map<String, Object> params) {
        return ResponseData.buildSuccessResponse(passengerMapper.getUuids(params));
    }

    @Override
    public ResponseData<List<String>> getUuidsByMobiles(String[] mobiles) {
        return ResponseData.buildSuccessResponse(passengerMapper.getUuidsByMobiles(mobiles));
    }

    @Override
    public ResponseData<Map<String, Object>> inviteRegister(Map<String, Object> params) {
        String inviter = (String) params.get("inviter");
        Integer inviterType = (Integer) params.get("inviterType");
        String appid = (String) params.get("appid");
        String invitee = (String) params.get("invitee");
        String adCode = (String) params.get("adCode");
        //乘客新增
        PassengerDto passengerDto = new PassengerDto();
        passengerDto.setMobile(invitee);
        passengerDto.setNickname(RandomNameUtils.randomName());
        passengerDto.setAppid(appid);
        // 默认男
        passengerDto.setSex(PassengerConstant.SEX_MAN);
        passengerDto.setUuid(StringUtils.buildUUID());
        passengerDto.setCreateOn(new Date());
        passengerDto.setStatus(1);
        // 只有登录之后才是激活状态
        passengerDto.setActive(0);
        if (passengerMapper.add(passengerDto) > 0) {
            //同步新增乘客账户
            SysAccountPassengerDto accountPassengerDto = new SysAccountPassengerDto();
            accountPassengerDto.setUuid(passengerDto.getUuid());
            accountPassengerDto.setAppid(appid);
            accountPassengerDto.setAccountName(passengerDto.getNickname());
            accountPassengerDto.setPresentBalance(BigDecimal.ZERO);
            accountPassengerDto.setRechargeBalance(BigDecimal.ZERO);
            accountPassengerDto.setAlipayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setTenpayAccumulate(BigDecimal.ZERO);
            accountPassengerDto.setCreateOn(new Date());
            sysAccountPassengerService.add(accountPassengerDto);
            //记录邀请关系
            MarketingInviteLogDto inviteLogDto = new MarketingInviteLogDto();
            inviteLogDto.setUuid(StringUtils.buildUUID());
            inviteLogDto.setInvitee(invitee);
            inviteLogDto.setInviter(inviter);
            inviteLogDto.setInviterType(inviterType);
            inviteLogDto.setInviteeType(1);
            inviteLogDto.setCreateOn(new Date());
            // 默认未领取
            inviteLogDto.setInviterReceiveStatus(0);

            String channelUuid = null;
            String registerRemindInfo = "恭喜你，你已经注册成功，请赶快去下载吧";
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("registerRemindInfo", registerRemindInfo);
            // 分享者为乘客时
            if (inviterType == 1) {
                channelUuid = passengerInvite(inviteLogDto, inviter, adCode, passengerDto.getUuid(), resultMap);
            }
            //分享者为司机时
            if (inviterType == 2) {
                channelUuid = driverInvite(inviteLogDto, inviter, adCode, passengerDto.getUuid(), resultMap);
            }
            // 记录渠道号
            if (StringUtils.isNotEmpty(channelUuid)) {
                // 修改用户来源渠道
                passengerDto.setChannelUuid(channelUuid);
                passengerMapper.edit(passengerDto);
                // 记录渠道邀请日志
                MarketingChannelLogDto marketingChannelLogDto = new MarketingChannelLogDto();
                marketingChannelLogDto.setUuid(StringUtils.buildUUID());
                marketingChannelLogDto.setChannelUuid(channelUuid);
                marketingChannelLogDto.setUserUuid(passengerDto.getUuid());
                marketingChannelLogDto.setAppid(passengerDto.getAppid());
                marketingChannelLogDto.setCreateOn(passengerDto.getCreateOn());
                marketingChannelLogDto.setNewUser(1);
                marketingChannelLogService.add(marketingChannelLogDto);
            }
            // 注册成功之后记录邀请日志
            marketingInviteLogService.add(inviteLogDto);
            POOL.execute(() -> {
                Map<String, Object> regParams = new HashMap<>(8);
                regParams.put("uuid", StringUtils.buildUUID());
                regParams.put("appid", passengerDto.getAppid());
                regParams.put("passengerUuid", passengerDto.getUuid());
                if (inviterType == 1) {
                    regParams.put("type", 2);
                }
                if (inviterType == 2) {
                    regParams.put("type", 3);
                }
                passengerLogMapper.saveRegisterLog(regParams);
            });
            return ResponseData.buildSuccessResponse(resultMap);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "注册失败");
    }

    private String driverInvite(MarketingInviteLogDto inviteLogDto, String inviter, String adCode, String passengerUuid, Map<String, Object> resultMap) {
        // 被邀请者 发送优惠券
        List<MarketingCouponDto> inviteeCouponList = new ArrayList<>();
        // 定义被邀请的乘客优惠券集合（保存到数据库中）
        List<PassengerCouponDto> inviteeCouponDtoList = new ArrayList<>();

        Map<String, Object> giftParams = new HashMap(8);
        giftParams.put("type", 3);
        giftParams.put("subType", 1);
        giftParams.put("status", 1);
        //限制查询剩余数量大于0
        giftParams.put("hasRemain", 1);
        // 获取当前司机邀请礼包
        MarketingGiftDto marketingGiftDto = marketingGiftService.get(giftParams).getData();
        if (marketingGiftDto != null) {
            // 1. 被邀请者奖励
            switch (marketingGiftDto.getInvitedRewardMethod()) {
                case 1:
                    MarketingGiftDto paramsBean = new MarketingGiftDto();
                    paramsBean.setType(3);
                    // 司机邀请乘客礼包
                    paramsBean.setSubType(1);
                    // 被邀请者 获取司机邀请礼包的优惠券
                    inviteeCouponList = marketingCouponService.getActiveCouponsByGift(paramsBean).getData();
                    break;
                case 2:
                    //领取新人注册礼包
                    inviteeCouponList = getRegisterCoupon(adCode);
                    break;
                case 3:
                    MarketingGiftDto giftDto = new MarketingGiftDto();
                    giftDto.setType(3);
                    // 司机邀请乘客礼包
                    giftDto.setSubType(1);
                    // 被邀请者 获取司机邀请礼包的优惠券
                    inviteeCouponList = marketingCouponService.getActiveCouponsByGift(giftDto).getData();
                    inviteeCouponList.addAll(getRegisterCoupon(adCode));
                    break;
                default:
                    break;
            }
            //优惠券金额价值
            Double couponValue = 0d;
            for (MarketingCouponDto marketingCouponDto : inviteeCouponList) {
                PassengerCouponDto inviteeCouponDto = new PassengerCouponDto();
                inviteeCouponDto.setUuid(StringUtils.buildUUID());
                inviteeCouponDto.setAppid(marketingCouponDto.getAppid());
                inviteeCouponDto.setStatus(1);
                inviteeCouponDto.setCreateOn(new Date());
                inviteeCouponDto.setPassengerUuid(passengerUuid);
                inviteeCouponDto.setCityNames(marketingCouponDto.getCityNames());
                inviteeCouponDto.setCityUuids(marketingCouponDto.getCityUuids());
                inviteeCouponDto.setSysCouponUuid(marketingCouponDto.getUuid());
                //设置优惠券过期时间
                setCouponExpireTime(marketingCouponDto, inviteeCouponDto);
                inviteeCouponDtoList.add(inviteeCouponDto);
                couponValue = couponValue + (marketingCouponDto.getHighestMoney() != null ? marketingCouponDto.getHighestMoney() : marketingCouponDto.getMoney());
            }
            if (couponValue > 0) {
                resultMap.put("registerRemindInfo", "我们已经发送价值" + String.format("%.1f", couponValue) + "元优惠券到您的账户，请赶快下载使用吧！");
            }
            //批量保存乘客优惠券
            if (CollectionUtils.isNotEmpty(inviteeCouponDtoList)) {
                passengerCouponService.addBatch(inviteeCouponDtoList);
            }
            // 减少礼包数量
            POOL.execute(() -> setGiftRemainNumberSub(3, 1, null, 1));
            // 2. 邀请者奖励
            // 判断当前礼包返现领取类型 如果是完成注册就领取 则直接返现
            if (2 == marketingGiftDto.getGetMode()) {
                // 获取邀请该乘客的司机
                DriverDto driverDto = driverService.get(MapUtils.build("mobile", inviter)).getData();
                drawDriverCashBack(driverDto, marketingGiftDto.getDriverCashback(), inviteLogDto.getUuid());
            }
            if (1 == marketingGiftDto.getGetMode()) {
                inviteLogDto.setCashBack(marketingGiftDto.getDriverCashback());
            }
            // 获取司机邀请乘客渠道id
            return marketingChannelService.findChannelUuidByConditions(MapUtils.build("type", 3)).getData();
        }
        return null;
    }

    private String passengerInvite(MarketingInviteLogDto inviteLogDto, String inviter, String adCode, String passengerUuid, Map<String, Object> resultMap) {
        //邀请者 发送优惠券
        List<MarketingCouponDto> inviterCouponList = new ArrayList<>();
        //被邀请者 发送优惠券
        List<MarketingCouponDto> inviteeCouponList = new ArrayList<>();
        // 定义被邀请的乘客优惠券集合（保存到数据库中）
        List<PassengerCouponDto> inviteeCouponDtoList = new ArrayList<>();
        // 定义邀请者优惠券集合（保存到数据库中）
        List<PassengerCouponDto> inviterCouponDtoList = new ArrayList<>();

        List<String> inviterUuids = passengerMapper.getUuids(MapUtils.build("mobile", inviter));
        if (CollectionUtils.isNotEmpty(inviterUuids)) {
            Map<String, Object> marketingGiftMap = new HashedMap(4);
            marketingGiftMap.put("type", 2);
            marketingGiftMap.put("status", 1);
            MarketingGiftDto marketingGift = marketingGiftService.findGiftByMap(marketingGiftMap).getData();
            if (marketingGift != null && marketingGift.getStatus() == 1) {
                //被邀请人礼包
                switch (marketingGift.getInvitedRewardMethod()) {
                    case 1:
                        // 获取被邀请者自定义礼包
                        Map<String, Object> map = new HashedMap();
                        map.put("giftUuid", marketingGift.getUuid());
                        map.put("giftType", 2);
                        map.put("couponSubType", 2);
                        inviteeCouponList = marketingCouponService.getActiveCouponsByMap(map).getData();
                        break;
                    case 2:
                        // 领取新人注册礼包
                        inviteeCouponList = getRegisterCoupon(adCode);
                        break;
                    case 3:
                        // 领取新人注册礼包+自定义礼包
                        // 获取被邀请者自定义礼包
                        Map<String, Object> couponMap = new HashedMap();
                        couponMap.put("giftUuid", marketingGift.getUuid());
                        couponMap.put("giftType", 2);
                        couponMap.put("couponSubType", 2);
                        ResponseData<List<MarketingCouponDto>> coupons = marketingCouponService.getActiveCouponsByMap(couponMap);
                        inviteeCouponList = coupons.getData();
                        inviteeCouponList.addAll(getRegisterCoupon(adCode));
                        break;
                    default:
                        break;
                }
                // 邀请人礼包
                if (marketingGift.getInviteRewardMethod() == 1 && marketingGift.getGetMode() == 2) {
                    Map<String, Object> couponMap = new HashedMap();
                    couponMap.put("giftUuid", marketingGift.getUuid());
                    couponMap.put("giftType", 2);
                    couponMap.put("couponSubType", 1);
                    ResponseData<List<MarketingCouponDto>> coupons = marketingCouponService.getActiveCouponsByMap(couponMap);
                    inviterCouponList = coupons.getData();
                    inviteLogDto.setInviterReceiveStatus(1);
                }
                //优惠券金额价值
                Double couponValue = 0d;
                //被邀请人获取优惠券
                for (MarketingCouponDto marketingCouponDto : inviteeCouponList) {
                    PassengerCouponDto inviteeCouponDto = new PassengerCouponDto();
                    inviteeCouponDto.setUuid(StringUtils.buildUUID());
                    inviteeCouponDto.setStatus(1);
                    inviteeCouponDto.setAppid(marketingCouponDto.getAppid());
                    inviteeCouponDto.setCreateOn(new Date());
                    inviteeCouponDto.setPassengerUuid(passengerUuid);
                    inviteeCouponDto.setSysCouponUuid(marketingCouponDto.getUuid());
                    inviteeCouponDto.setCityNames(marketingCouponDto.getCityNames());
                    inviteeCouponDto.setCityUuids(marketingCouponDto.getCityUuids());
                    //设置优惠券过期时间
                    setCouponExpireTime(marketingCouponDto, inviteeCouponDto);
                    inviteeCouponDto.setCreateOn(new Date());
                    inviteeCouponDtoList.add(inviteeCouponDto);
                    couponValue = couponValue + (marketingCouponDto.getHighestMoney() != null ? marketingCouponDto.getHighestMoney() : marketingCouponDto.getMoney());
                }
                if (couponValue > 0) {
                    resultMap.put("registerRemindInfo", "我们已经发送价值" + String.format("%.1f", couponValue) + "元优惠券到您的账户，请赶快下载使用吧！");
                }
                //邀请人获取优惠券
                for (MarketingCouponDto marketingCouponDto : inviterCouponList) {
                    PassengerCouponDto inviterCouponDto = new PassengerCouponDto();
                    inviterCouponDto.setUuid(StringUtils.buildUUID());
                    inviterCouponDto.setAppid(marketingCouponDto.getAppid());
                    inviterCouponDto.setStatus(1);
                    inviterCouponDto.setCreateOn(new Date());
                    inviterCouponDto.setPassengerUuid(inviterUuids.get(0));
                    inviterCouponDto.setSysCouponUuid(marketingCouponDto.getUuid());
                    inviterCouponDto.setCityNames(marketingCouponDto.getCityNames());
                    inviterCouponDto.setCityUuids(marketingCouponDto.getCityUuids());
                    //设置优惠券过期时间
                    setCouponExpireTime(marketingCouponDto, inviterCouponDto);
                    inviterCouponDtoList.add(inviterCouponDto);
                }
                POOL.execute(() -> setGiftRemainNumberSub(2, 1, null, 1));
                //批量保存被邀请乘客优惠券
                if (!inviteeCouponDtoList.isEmpty()) {
                    //批量新增乘客优惠券
                    passengerCouponService.addBatch(inviteeCouponDtoList);
                }
                //批量保存邀请者(乘客)的优惠券
                if (!inviterCouponDtoList.isEmpty()) {
                    //批量新增乘客优惠券
                    passengerCouponService.addBatch(inviterCouponDtoList);
                }
                // 返回乘客邀请乘客渠道id
                return marketingChannelService.findChannelUuidByConditions(MapUtils.build("type", 2)).getData();
            }
        }
        return null;
    }

    @Override
    public ResponseData<PageVo<PassengerDto>> queryDrawPage(AdminGiftUuidPageParam giftUuidPageParam) {
        PageBounds pageBounds = new PageBounds(giftUuidPageParam.getPageNum(), giftUuidPageParam.getPageSize());
        PageList<PassengerDto> pageList = passengerMapper.queryDrawPage(MapUtils.convertObjToMap(giftUuidPageParam), pageBounds);
        PageVo pageVo = new PageVo(giftUuidPageParam.getPageNum(), giftUuidPageParam.getPageSize(),
                pageList.getPaginator().getTotalCount());
        pageVo.setItems(pageList);
        return ResponseData.buildSuccessResponse(pageVo);
    }

    @Override
    public ResponseData<List<String>> getSleepPassengerUuids(Integer unusedDays) {
        return ResponseData.buildSuccessResponse(passengerMapper.getSleepPassengerUuids(unusedDays));
    }

    @Override
    public ResponseData<List<String>> getHighFrequencyPassengerUuids(Integer highFrequencyDays, Integer highFrequencyNum) {
        return ResponseData.buildSuccessResponse(passengerMapper.getHighFrequencyPassengerUuids(highFrequencyDays, highFrequencyNum));
    }

    @Override
    public ResponseData<List<PassengerDto>> getPassengerByUuids(List<String> passengerUuids) {
        return ResponseData.buildSuccessResponse(passengerMapper.getPassengerByUuids(passengerUuids));
    }

    @Override
    public ResponseData<PassengerVo> selInfo(String uuid) {
        List<PassengerDto> passengerDtos = passengerMapper.list(MapUtils.build("uuid", uuid));
        if (CollectionUtils.isEmpty(passengerDtos)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "查不到该乘客");
        }
        PassengerDto passengerDto = passengerDtos.get(0);
        PassengerVo passengerVo = new PassengerVo();
        BeanUtils.copyProperties(passengerDto, passengerVo);
        passengerVo.setIsFirst(PassengerConstant.IS_NO_FIRST);
        passengerVo.setUuid(uuid);
        return ResponseData.buildSuccessResponse(passengerVo);
    }

    @Override
    public void incrPasOrderCountByUuid(String passengerUuid) {
        passengerMapper.incrPasOrderCountByUuid(passengerUuid);
    }


    @Override
    public ResponseData<Boolean> abort(AdminPassengerAbortParam passengerAbortParam) {
        //记录 封号/解封 的历史日志(Created by XiuYin.Cui)
        PassengerBlockedLogDto passengerBlockedLogDto = new PassengerBlockedLogDto();
        passengerBlockedLogDto.setUuid(StringUtils.buildUUID());
        passengerBlockedLogDto.setPassengerUuid(passengerAbortParam.getUuid());
        passengerBlockedLogDto.setCreateBy(passengerAbortParam.getUserUuid());
        passengerBlockedLogDto.setCreateOn(new Date());
        passengerBlockedLogDto.setType(passengerAbortParam.getStatus());
        passengerBlockedLogDto.setRemark(passengerAbortParam.getAbortRemark());
        passengerBlockedLogDto.setReason(passengerAbortParam.getAbortRemark());

        PassengerDto passengerDto = new PassengerDto();
        BeanUtils.copyProperties(passengerAbortParam, passengerDto);
        if (passengerAbortParam.getStatus() == 1) {
            List<PassengerBlockedLogDto> list = passengerPunishLogMapper.list(MapUtils.build("passengerUuid", passengerDto.getUuid()));
            if (CollectionUtils.isNotEmpty(list)) {
                Date blockStart = list.get(0).getBlockStart();
                passengerBlockedLogDto.setBlockStart(blockStart);
                passengerBlockedLogDto.setBlockEnd(new Date());
            }
            passengerDto.setAbortTime(null);
            passengerDto.setAbortRemark(null);
        } else {
            passengerBlockedLogDto.setBlockStart(new Date());
            passengerBlockedLogDto.setBlockEnd(passengerDto.getAbortTime());
            //封号长连接请求
            Map<String, Object> dataMap = MapUtils.build();
            dataMap.put("title", "后台封号");
            dataMap.put("content", "乘客已被后台管理员封号");
            PushContent pushContent = new PushContent(PushContent.To.PASSENGER, passengerDto.getAppid(), PushContent.ORDER_ADMIN_PASSENGER_LOGOUT, false, dataMap);
            pushService.sendMessage(passengerDto.getUuid(), pushContent);
        }

        Boolean execute = transactionTemplate.execute(transactionStatus -> {
            Integer edit = passengerMapper.edit(passengerDto);
            Integer add = passengerPunishLogMapper.add(passengerBlockedLogDto);
            return edit > 0 && add > 0;
        });
        return ResponseData.buildSuccessResponse(execute);
    }


    /**
     * 设置减少礼包数量
     *
     * @param type
     * @param status
     * @param passengerCityUuid
     * @param remainNo
     */
    private void setGiftRemainNumberSub(int type, int status, String passengerCityUuid, int remainNo) {
        Map<String, Object> giftParams = new HashMap(8);
        giftParams.put("type", type);
        giftParams.put("status", status);
        giftParams.put("sendCity", passengerCityUuid);
        //限制查询剩余数量大于0
        giftParams.put("hasRemain", 1);
        ResponseData<List<MarketingGiftDto>> responseData = marketingGiftService.list(giftParams);
        if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
            List<MarketingGiftDto> marketingGiftDtoList = responseData.getData();
            for (MarketingGiftDto marketingGiftDto : marketingGiftDtoList) {
                MarketingGiftDto upGiftDto = new MarketingGiftDto();
                upGiftDto.setUuid(marketingGiftDto.getUuid());
                upGiftDto.setRemainNumber(marketingGiftDto.getRemainNumber() - remainNo);
                marketingGiftService.edit(upGiftDto);
            }
        }
    }

    /**
     * 更新缓存
     *
     * @param token
     * @param passengerVo
     * @return
     */
    private void updateCached(String token, PassengerVo passengerVo) {
        // 删除旧的 token，防止多方登陆
        Object oldToken = redisCacheService.get(passengerVo.getUuid());
        if (oldToken != null) {
            redisCacheService.delete((String) oldToken);
        }
        Map<String, String> result = new HashMap<>(8);
        result.put("uuid", passengerVo.getUuid());
        result.put("nickName", passengerVo.getNickname());
        result.put("sex", StringUtils.isNull(passengerVo.getSex()) ? "" : passengerVo.getSex().toString());
        result.put("mobile", passengerVo.getMobile());
        result.put("face", passengerVo.getFace());
        result.put("status", String.valueOf(passengerVo.getStatus()));
        //添加缓存
        redisCacheService.set(token, result);
        redisCacheService.set(passengerVo.getUuid(), token);

    }

    private List<MarketingCouponDto> getRegisterCoupon(String adCode) {
        String passengerCityUuid = passengerCityUuid(adCode);
        //获取注册礼包
        MarketingGiftDto giftParam = new MarketingGiftDto();
        giftParam.setType(1);
        giftParam.setSendCity(passengerCityUuid);
        List<MarketingCouponDto> couponList = marketingCouponService.getActiveCouponsByGift(giftParam).getData();
        //如果adcode为空 以上注册礼包数为空则领取默认注册礼包
        if (StringUtils.isEmpty(adCode) || CollectionUtils.isEmpty(couponList)) {
            //加上全国的礼包
            giftParam.setSendCity("ALL");
            couponList.addAll(marketingCouponService.getActiveCouponsByGift(giftParam).getData());
        }
        logger.info("adcode:{} passengerCityUuid 是:{}", adCode, passengerCityUuid);
        POOL.execute(() -> setGiftRemainNumberSub(1, 1, passengerCityUuid, 1));
        return couponList;
    }

    /**
     * 领取司机返现金额
     *
     * @param driverDto
     * @param driverCashback
     */
    private void drawDriverCashBack(DriverDto driverDto, BigDecimal driverCashback, String inviteLogUuid) {
        if (driverDto != null) {
            // 平台账户
            ResponseData<SysAccountPlatformDto> responseData = sysAccountPlatformService.getByAppid(driverDto.getAppid());
            if (!responseData.isSuccess() || responseData.getData() == null) {
                logger.warn("获取不到平台账户信息，appid:{}", driverDto.getAppid());
                return;
            }
            SysAccountPlatformDto accountPlatformDto = responseData.getData();
            // 司机账户
            ResponseData<SysAccountDriverDto> driverWrapper = sysAccountDriverService.get(driverDto.getUuid());
            if (!driverWrapper.isSuccess() || driverWrapper.getData() == null) {
                logger.warn("获取不到司机账户信息，driverUuid:{}", driverDto.getUuid());
                return;
            }
            SysAccountDriverDto accountDriverDto = driverWrapper.getData();
            // 司机可提现余额
            BigDecimal canFrowardBalance = Optional.of(accountDriverDto.getCanFrowardBalance()).orElse(BigDecimal.ZERO);

            //司机奖励流水记录
            FinanceInviteRewardDto inviteRewardDto = new FinanceInviteRewardDto();
            inviteRewardDto.setUuid(StringUtils.buildUUID());
            inviteRewardDto.setAppid(driverDto.getAppid());
            inviteRewardDto.setCourse(FinanceConstant.DRIVER_INVITE_PASSENGER_INVITE_REWARD);
            inviteRewardDto.setAmount(driverCashback);
            inviteRewardDto.setBusinessUuid(inviteLogUuid);
            inviteRewardDto.setDescription("司机邀请乘客获得" + driverCashback + "元奖励");
            inviteRewardDto.setFinanceInflow(driverDto.getUuid());
            inviteRewardDto.setFinanceOutflow(accountPlatformDto.getUuid());
            inviteRewardDto.setFinanceNumber(StringUtils.buildUUID());
            inviteRewardDto.setStartBalance(canFrowardBalance);
            canFrowardBalance = canFrowardBalance.add(driverCashback);
            inviteRewardDto.setFinalBalance(canFrowardBalance);
            inviteRewardDto.setCreateOn(new Date());
            inviteRewardDto.setCreateBy(driverDto.getUuid());
            financeInviteRewardService.add(inviteRewardDto);

            //更新司机账户可提现余额
            accountDriverDto.setCanFrowardBalance(canFrowardBalance);
            accountDriverDto.setUpdateOn(new Date());

            //更新平台奖励累积
            BigDecimal rewardAccumulate = Optional.of(accountPlatformDto.getRewardAccumulate()).orElse(BigDecimal.ZERO);
            rewardAccumulate = rewardAccumulate.add(driverCashback);
            accountPlatformDto.setRewardAccumulate(rewardAccumulate);
            accountPlatformDto.setUpdateOn(new Date());

            transactionTemplate.execute(transactionStatus -> {
                sysAccountDriverService.edit(accountDriverDto);
                sysAccountPlatformService.edit(accountPlatformDto);
                return Boolean.TRUE;
            });

        }
    }

    private String getAdCodeByLngLat(String lng, String lat) {
        if (StringUtils.isNotEmpty(lng) && StringUtils.isNotEmpty(lat)) {
            ResponseData<RegeoVo> responseData = locationService.regeo(Double.parseDouble(lng), Double.parseDouble(lat));
            if (responseData.isSuccess() && responseData.getData() != null) {
                RegeoVo.AddressComponent addressComponent = responseData.getData().getAddressComponent();
                if (addressComponent != null) {
                    return addressComponent.getAdcode();
                }
            }
        }
        return "";
    }

    /**
     * 根据优惠券设置的有效期类型设置乘客的优惠券有效期。
     * 1、如果优惠券有效期设置的是时间段，则乘客优惠券有效期直接设置对应时间段
     * 2、如果优惠券有效期设置的是获取时间开始几天后，则开始时间为当前时间，结束时间为获取后多少天的0点
     *
     * @param marketingCouponDto
     * @param passengerCouponDto
     */
    private void setCouponExpireTime(MarketingCouponDto marketingCouponDto, PassengerCouponDto passengerCouponDto) {
        //设置优惠券过期时间
        if (1 == marketingCouponDto.getTermType()) {
            passengerCouponDto.setUseStartTime(marketingCouponDto.getUseStartTime());
            Calendar c = Calendar.getInstance();
            c.setTime(marketingCouponDto.getUseEndTime());
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            c.set(Calendar.MILLISECOND, 0);
            c.set(Calendar.HOUR_OF_DAY, 23);
            passengerCouponDto.setUseEndTime(c.getTime());
        }
        if (2 == marketingCouponDto.getTermType()) {
            Calendar c = Calendar.getInstance();
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            c.set(Calendar.MILLISECOND, 0);
            passengerCouponDto.setUseStartTime(c.getTime());
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            c.set(Calendar.MILLISECOND, 0);
            c.add(Calendar.DATE, marketingCouponDto.getUseExpireTime() - 1);
            passengerCouponDto.setUseEndTime(c.getTime());
        }
    }

    /**
     * 获取乘客简易信息
     *
     * @param uuid
     * @return
     */
    @Cached(name = "jetCache:assets:queyrSimpleInfoById:", key = "#uuid", expire = 300)
    @Override
    public ResponseData<PassengerSimpleInfoVo> queyrSimpleInfoById(String uuid) {
        PassengerSimpleInfoVo passengerSimpleInfoVo = passengerMapper.queyrSimpleInfoById(uuid);
        if (passengerSimpleInfoVo != null) {
            return ResponseData.buildSuccessResponse(passengerSimpleInfoVo);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "查询失败");
    }

    @Override
    public Boolean editByToken(PassengerDto passengerDto) {
        return passengerMapper.editByToken(passengerDto);
    }
}
